#pragma once
#include <iostream>
#include <string>
#include "user.hpp"
#include <sqlite3.h>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define PATH "Data.db"
#define TAB_T 1024

using namespace std;
// template <typename T>
class Option
{
public:
    virtual void init() = 0;
    virtual void insert_info(User &info) = 0;
    virtual void delete_info(string &info) = 0;
    virtual void update_info(User &info, string &name) = 0;
    virtual bool find(string &name) = 0;
    virtual void display() = 0;

};

int find_all(void *data, int columnCount, char **columnValue, char **columnName)
{
    // User user;

    // user.set_id(atoi((columnValue[0])));
    // user.set_name(columnValue[1]);
    // user.set_age(columnValue[2]);
    // user.set_tel(columnValue[3]);
    // user.set_addr(columnValue[4]);

    // cout << user << endl;
    cout << "id: " << columnValue[0] << "name: " << columnValue[1] << "age: " << columnValue[2]
         << "tel: " << columnValue[3] << "addr: " << columnValue[4] << endl;
    return 0;
}
int find_one(void *data, int columnCount, char **columnValue, char **columnName)
{
    *((int *)data) = 11;
    return 0;
}

// template <typename T>
class Sql : public Option
{
private:
    // string name_;
public:
    Sql() = default;

    // Sql(string name):name_(name){};
    bool sql_exec(string sql)
    {
        sqlite3 *db;
        int tmp;
        char *errmsg;
        sqlite3_open(PATH, &db);

        if ((tmp = sqlite3_exec(db, sql.c_str(), NULL, NULL, &errmsg)) != SQLITE_OK)
        {
            cout << "sql exe error: " << sqlite3_errmsg(db) << endl;
            sqlite3_close(db);
            return false;
        }
        else
        {
            sqlite3_close(db);
            return true;
        }
    }
    void init() override
    {

        string sql = "CREATE TABLE IF NOT EXISTS contact (ID INTEGER PRIMARY KEY AUTOINCREMENT , NAME TEXT , AGE TEXT , TEL TEXT, ADDR TEXT)";
        if (sql_exec(sql))
        {
            cout << "sql init successful" << endl;
        }
        else
        {
            cout << "sql init error" << endl;
        }
    }

    void insert_info(User &info) override
    {
        char sql[TAB_T] = {0};
        sprintf(sql, "INSERT INTO contact(name, age, tel, addr) VALUES('%s', '%s', '%s', '%s')", info.name, info.age, info.tel, info.addr);
        if (sql_exec(sql))
        {
            cout << "sql insert successful" << endl;
        }
        else
        {
            cout << "sql insert error" << endl;
        }
    }
    void delete_info(string &name) override
    {
        char sql[TAB_T] = {0};
        sprintf(sql, "DELETE FROM contact WHERE name='%s'", name.c_str());

        if (sql_exec(sql))
        {
            cout << "sql delete successful" << endl;
        }
        else
        {
            cout << "sql delete error" << endl;
        }
    }
    void update_info(User &info, string &name) override
    {
        char sql[TAB_T] = {0};
        sprintf(sql, "UPDATE contact set name='%s', age='%s', tel='%s', addr='%s' WHERE name='%s'", info.name, info.age, info.tel, info.addr, name.c_str());
        if (sql_exec(sql))
        {
            cout << "sql update successful" << endl;
        }
        else
        {
            cout << "sql update error" << endl;
        }
    }

    // int find(void *data, int columnCount, char **columnValue, char **columnName)
    // {
    //     User user;
    //     return 0;
    // }

    bool find(string &name) override
    {
        char sql[TAB_T] = {0};
        sprintf(sql, "SELECT * FROM contact where name='%s'", name.c_str());

        sqlite3 *db;
        char *errmsg;
        int tmp;
        int judge = 10;

        sqlite3_open(PATH, &db);
        if ((tmp = sqlite3_exec(db, sql, find_one, (void *)&judge, &errmsg)) != SQLITE_OK)
        {
            cout << "exec error: " << sqlite3_errmsg(db) << endl;
        }
        sqlite3_close(db);
        if (judge == 11)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    void display() override
    {
        char sql[TAB_T] = "SELECT * FROM contact ";

        sqlite3 *db;
        char *errmsg;
        int tmp;

        sqlite3_open(PATH, &db);
        if ((tmp = sqlite3_exec(db, sql, find_all, NULL, &errmsg)) != SQLITE_OK)
        {
            cout << "exec error: " << sqlite3_errmsg(db) << endl;
        }

        sqlite3_close(db);
    }
    ~Sql() = default;
};
